
#include "datarcver.h"

#define GetOffset(p, initnal)   ((uint32_t)((void*)p - (void*)(initnal)))


#undef      DebugLevel
#define     DebugLevel  DebugError

/** ***************************************************************************
 * @use_for:该文件用于初始化一个JSON数据接受器,为数据接收类的一个特例,使用特点的参数来初始
 * 化数据接收器,用户只需自定义数据处理函数
 * @data:2020-10-9
 * @author:socbis
 *
 * */

static void IsJSONHead(struct DataReceiver* this);
static void* SearchJSONHead(const void* buf, const uint32_t buflen);
static unsigned int cJSON_GetJsonStrLen(const char* json, 
                                const unsigned int maxlen);

/** ###########################################################################
 * Use For      ---- 初始化 JSON 接收器
 * Param        ---- new 给定需要初始化的接收器对象
 *                   buflen 给定接收器的部分长度
 *                   packprocessor 指定自定义的数据接收器数据处理函数
 * */

bool JSONRecverInit(DataReceiver_t* new, uint32_t buflen, 
                    void (*packprocessor)(struct DataReceiver* , void* ))
{
    if (DataReveiver_Init(new, 1, buflen) == false) {
        DebugE("Error : exit with DataReveiver_Init() return false\n");
        return false;
    }

    new->minheadlen = 2;
    new->IsHead = IsJSONHead,
    new->SearchHead = SearchJSONHead;
    new->PackProcessor = 
        (void (*)(struct DataReceiver* , void* ))packprocessor;
    return true;
}





/** ****************************************************************************
 * Use For     ---- 判断数据是否包含Json头
 * Note         --- 该函数为接收器的成员函数，不被主动调用
 * */
static void IsJSONHead(struct DataReceiver* this)
{
    if (Is_JsonHead(this->p_head)) {
        this->packlen = cJSON_GetJsonStrLen(this->p_head, 
                                            this->select->readlen);

        if (this->packlen == 0) {
            this->packtype = PackType_HalfPack;
            return;
        }
        DebugT("Is_JsonHead  %d\n", this->packlen);
        this->p_next += this->packlen;
        this->packtype = PackType_Json;
    } else {
        this->packtype = PackType_Invalid;
    }
}


/** ****************************************************************************
 * Use For     ---- 在数据中搜索Json头
 * Note         --- 该函数为接收器的成员函数，不被主动调用
 * */
static void* SearchJSONHead(const void* buf, const uint32_t buflen)
{
    uint8_t* p_buf = (uint8_t*)buf;

    while (!Is_JsonHead(p_buf)) {
        p_buf++;
        if (GetOffset(p_buf, buf) == buflen - 1) {
            return NULL;
        }
    }
    return p_buf;
}


/**
 * @note:
 * @para: json > 传入json字符串
 * 		 maxlen > 传入字符串的长度
 * @returnval:成功返回长度，失败返回 0
 * */
unsigned int cJSON_GetJsonStrLen(const char* json, const unsigned int maxlen)
{
    const char* p_json = json + 1;
    unsigned int lc = 0;
    if (*json != '{') return 0;
    lc = 1;
    while (1) {
        if (*p_json == '{') {
            if (p_json - json < maxlen) {
                lc++;
            }
            else {
                return 0;
            }
        }
        else if (*p_json == '}') {
            if (p_json - json < maxlen) {
                lc--;
            }
            else {
                return 0;
            }
            if (lc == 0) {
                return p_json - json + 1;
            }
        }
		else if (*p_json == 0) {
			return 0;
		}
        p_json++;
    }
    return 0;
}

